#include "TCPServer.hpp"
#include <memory>
#include "UserManual.hpp"
#include "ComputerProtocol.hpp"

void testComputerProtocol()
{
    // 测试序列化是否正确
    ComputerData::Request r(121342, 12, '+');
    // std::cout << "序列化：";
    std::string str = r.Serialize();
    std::cout << str << std::endl;
    // std::cout << "反序列化：";
    ComputerData::Request q;
    q.Deserialization(str);
    // std::cout << "------------------\n";
    ComputerData::Response p(1, q._x + q._y);
    // std::cout << "序列化：";
    std::string str2 = p.Serialize();
    std::cout << str2 << std::endl;
    // std::cout << "反序列化：";
    ComputerData::Response q2;
    q2.Deserialization(str2);

    std::string tmp = ComputerData::Decode(str);  // 
    if (tmp.empty()) printf("失败\n");
    else std::cout << tmp << std::endl;
    std::string tmp2 = ComputerData::Decode(str2);
    if (tmp.empty()) printf("失败\n");
    else std::cout << tmp2 << std::endl;
    std::cout << "-------------------------------\n";
    std::cout << str << "\n\n" << str2 << std::endl;
}

void test(void* argc)
{
    QiHai::TCPServerData* tmp = (QiHai::TCPServerData*)argc;
    std::string buffer;
    while (true)
    {
        if (QiHai::Sock::recv(tmp->_sock, buffer))
        {
            std::cout << "[" << tmp->_ip << ": " << tmp->_port << "]# ";
            std::cout << buffer << std::endl;  // 注意类似于endl和'\n'等需要刷新缓冲区的！务必记住
        }
        else break;

        QiHai::Sock::send(tmp->_sock, buffer);
    }
    exit(0);
}

void computer(void* argc)
{
    // 实现网络计算器的业务
    QiHai::TCPServerData* tmp = (QiHai::TCPServerData*)argc;
    std::string buffer;
    ComputerData::Request q;
    while (true)
    {
        if (QiHai::Sock::recv(tmp->_sock, buffer))
        {
            // printf("+++++++++1++++++++++++++\n");
            // 检查读取的是否完整
            std::string res = ComputerData::Decode(buffer);
            if (res.empty()) continue;  // 继续读

            std::cout << "[" << tmp->_ip << ": " << tmp->_port << "]# ";
            q.Deserialization(res);
            std::cout << q._x << q._op << q._y << std::endl;
        }
        else break;

        int result, code = 0;
        switch (q._op)
        {
        case '+':
            result = q._x + q._y;
            break;
        case '-':
            result = q._x - q._y;
            break;
        case '*':
            result = q._x * q._y;
            break;
        case '/':
            if (q._y != 0) result = q._x / q._y;
            else code = 1;
            break;
        default:
            code = 2;
            break;
        }
        ComputerData::Response p(code, result);
        QiHai::Sock::send(tmp->_sock, p.Serialize());
    }
}

int main(int argc, char *argv[])
{
    if (argc != 2)
    {
        User(argv[0]);
        exit(-1);
    }
    std::unique_ptr<QiHai::TCPServer> server(new QiHai::TCPServer(atoi(argv[1]), computer));
    server->init();
    server->start();

    // testComputerProtocol();
    return 0;
}